package www.ph.adali.happy.location;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.Looper;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;

import www.ph.adali.happy.MyApplication;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationAvailability;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;


public class GoogleLocation implements ILocation, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
    private static final String WAY = "google";
    private GoogleApiClient mGoogleApiClient = null;
    private final static long REQUEST_INTERVAL = 1000;                  //请求间隔
    private final static long REQUEST_FASTER_INTERVAL = 60 * 1000;            //最快请求间隔
    private final static long REQUEST_MAX_WAITTIME = 5 * 60 * 1000;           //最大等待时间
    private ILocationCallback locationCallback;
    private LocationListener mLocationListener;
//    private ResultCallback mResultCallback;
    private LocationCallback callback;

    public GoogleLocation(Context context, ILocationCallback pLocationCallback) {
        this.locationCallback = pLocationCallback;
        mGoogleApiClient = new GoogleApiClient.Builder(context.getApplicationContext())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        initListener();
    }

    private void initListener() {

        callback = new LocationCallback(){
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if(locationResult == null && locationResult.getLastLocation() == null){
                    locationCallback.onLocationFailed(LocationErrorType.TypeRequestLocationNull, WAY,null);
                }else{
                    Location lastLocation = locationResult.getLastLocation();
                    locationCallback.onLocationSuccess(new LocationData(lastLocation.getLatitude(),lastLocation.getLongitude(),lastLocation.getAccuracy(),WAY));
                }
            }
        };

    }

    @Override
    public void startLocation() {
        if (!mGoogleApiClient.isConnected()) {              // 如果没有打开
            if (!mGoogleApiClient.isConnectionCallbacksRegistered(this)) {
                mGoogleApiClient.registerConnectionCallbacks(this);
            }
            if (!mGoogleApiClient.isConnectionFailedListenerRegistered(this)) {
                mGoogleApiClient.registerConnectionFailedListener(this);
            }
            mGoogleApiClient.connect();                     // 打开定位
        } else {
            requestLocation();
        }
    }

    private void requestLocation() {
        if (ActivityCompat.checkSelfPermission(MyApplication.getApplication(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyApplication.getApplication(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        @SuppressLint("MissingPermission") LocationAvailability locationAvailability =
                LocationServices.FusedLocationApi.getLocationAvailability(mGoogleApiClient);
        if (null != locationAvailability && locationAvailability.isLocationAvailable()) {
            @SuppressLint("MissingPermission") Location lastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            if (null != lastLocation) {
                locationCallback.onLocationSuccess(new LocationData(lastLocation.getLatitude(), lastLocation.getLongitude(), lastLocation.getAccuracy(), WAY));
            } else {
                location();
            }
        } else {
            location();
        }
    }

    @SuppressLint("MissingPermission")
    private void location() {
        LocationRequest locationRequest = new LocationRequest();
        locationRequest.setInterval(REQUEST_INTERVAL);
        locationRequest.setFastestInterval(REQUEST_FASTER_INTERVAL);
        locationRequest.setMaxWaitTime(REQUEST_MAX_WAITTIME);
        locationRequest.setNumUpdates(1);                           //设置请求次数为1
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);            //设置高精度请求
//        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, mLocationListener).setResultCallback(mResultCallback);
        if (ActivityCompat.checkSelfPermission(MyApplication.getApplication(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyApplication.getApplication(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        LocationServices.getFusedLocationProviderClient(MyApplication.getApplication()).requestLocationUpdates(locationRequest, callback,Looper.myLooper());
    }



    @Override
    public void closeLocation() {
        if( mGoogleApiClient != null && mGoogleApiClient.isConnected() ) {
            if (!mGoogleApiClient.isConnectionCallbacksRegistered(this)){
                mGoogleApiClient.unregisterConnectionCallbacks(this);
            }
            if (!mGoogleApiClient.isConnectionFailedListenerRegistered(this)){
                mGoogleApiClient.unregisterConnectionFailedListener(this);
            }
//            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,mLocationListener);
            LocationServices.getFusedLocationProviderClient(MyApplication.getApplication()).removeLocationUpdates(callback);
            mGoogleApiClient.disconnect();
        }
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        requestLocation();
    }

    @Override
    public void onConnectionSuspended(int i) {
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        switch (connectionResult.getErrorCode()){
            case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED:
                locationCallback.onLocationFailed(LocationErrorType.TypeServiceVersionUpdateRequired,WAY,null);
                break;
            case ConnectionResult.SUCCESS:
                break;
            case ConnectionResult.API_UNAVAILABLE:
                locationCallback.onLocationFailed(LocationErrorType.TypeApiUnavailable,WAY,null);
                break;
            default:
                locationCallback.onLocationFailed(LocationErrorType.TypeOtherError,WAY,connectionResult.getErrorCode()+"");
                break;
        }
    }
}
